/**
 * Copyright (c) 2009-2011, chunquedong(YangJiandong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 
 * History:
 *     2010-05-05  Jed Young  Creation
 */
package chunmap.model.geom;

import java.util.List;

import chunmap.model.algorithm.RingAlgorithm;
import chunmap.model.coord.CoordinateSeq;
import chunmap.model.coord.Position;
import chunmap.model.coord.Transform;

/**
 * @author chunquedong
 * 
 */
public class Ring extends LineString {

	/**
	 * @param pointList
	 */
	public Ring(List<Position> pointList) {
		super(pointList);
		check();
	}

	public Ring(Position[] pointList) {
		super(pointList);
		check();
	}
	
	public Ring(CoordinateSeq points) {
		super(points);
		check();
	}
	
	private void check(){
		if (size() < 4) {
			throw new IllegalArgumentException(
					"least three points(four pair coordinate)");
		}
		Position fp = super.firstPoint();
		Position lp = super.lastPoint();
		if (!(fp.equals(lp)))
			throw new IllegalArgumentException(
					"firstPoint mast same to lastPoint in a ring");
	}
	
	@Override
	public Geometry transform(Transform transf) {
		LineString ls = (LineString) super.transform(transf);
		return ls.toLinearRing();
	}

	@Override
	protected boolean isSimple() {
		if (!super.isSimple())
			return false;

		Position fp = super.firstPoint();
		Position tp = super.lastPoint();
		for (int i = 1, n = size() - 1; i < n; i++) {
			Position p = getPoint(i);
			if (fp.equals(p) || tp.equals(p)) {
				return false;
			}
		}
		return true;
	}
	
	//------------------------------------------------------------------------util

    public boolean containIn(Position point)
    {
        if (!super.getEnvelop().contain(point))
        {
            return false;
        }
        if (super.onLineString(point))
            return true;

        return RingAlgorithm.containIn(super.getPoints(), point);
    }
    public boolean clockwise()
    {
        return RingAlgorithm.clockwise(super.getPoints());
    }
    public double computeArea()
    {
        return RingAlgorithm.computeArea(super.getPoints());
    }
    public boolean containLineStringIn(LineString l2)
    {
        if (!super.getEnvelop().contain(l2.getEnvelop()))
        {
            return false;
        }
        return RingAlgorithm.containLineString(super.getPoints(), l2.getPoints());
    }

    public Polygon toPolygon()
    {
        return new Polygon(this);
    }
    
    @Override
    public boolean hasIntersection(LineString l2)
    {
        if (super.hasIntersection(l2)){
            return true;
        }else if(this.containLineStringIn(l2)){
        		return true;
        }else{
        	return false;
        }
    }
}